package com.apartment.aop;

/**
 * 2 * @Author: xy
 * 3 * @Date: 2021/08/29 下午 2:28:00
 */

import com.alibaba.fastjson.JSON;
import com.apartment.entity.SysLog;
import com.apartment.service.house.HouseService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Objects;

/**
 * 系统日志：切面处理类
 */
@Configuration
@ComponentScan("com.apartment.aop")
@ComponentScan("com.apartment.service.house.impl")

@Aspect
@Component
public class SysLogAspect {
    @Autowired
    private HouseService houseService;

    //定义切点 @Pointcut

    //在注解的位置切入代码
    @Pointcut("@annotation( com.apartment.aop.MyLog)")
    public void logPoinCut() {
    }

    //切面 配置通知
    @Around("logPoinCut()")
    public Object saveSysLog(ProceedingJoinPoint joinPoint) {
        //保存日志
        SysLog sysLog = new SysLog();

        //从切面织入点处通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取切入点所在的方法
        Method method = signature.getMethod();

        //获取操作
        MyLog myLog = method.getAnnotation(MyLog.class);

        //保存获取的操作

        //获取请求的类名
        String className = joinPoint.getTarget().getClass().getName();
        //获取请求的方法名
        String methodName = method.getName();
        sysLog.setMethod(methodName);

        //请求的参数
        Object[] args = joinPoint.getArgs();
        //将参数所在的数组转换成json
        String params = JSON.toJSONString(args);
        sysLog.setParams(params);

        Package aPackage = joinPoint.getTarget().getClass().getPackage();
        sysLog.setModule(aPackage.getName());
        Object object = null;
        long startTime = System.currentTimeMillis();
        try {
            // 切入点方法 service层方法
            object = joinPoint.proceed();
            // 设置结束时间
            long endTime = System.currentTimeMillis();
            sysLog.setTime(endTime - startTime);
            // 设置执行结果
            sysLog.setResult("执行成功");
        } catch (Throwable throwable) {
            // 设置执行时间
            long endTime = System.currentTimeMillis();
            sysLog.setTime(endTime - startTime);
            // 设置执行结果
            sysLog.setResult("执行失败");
        }
        // userLog模型数据全部
        sysLog.setCreateDate(new Date());

        //获取用户名
        //此例子用到了ShiroUtils框架来实现获取用户名，此处还可以用session来获取登录操作名
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        String code = (String) request.getSession().getAttribute("username");
        System.out.println(code);
        if (code == null || code.equals("")) {
            sysLog.setUsername("未登录");
        } else {
            sysLog.setUsername((String) request.getSession().getAttribute("username"));
        }
//        //获取用户ip地址
//        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
//        sysLog.setIp(IPUtils.getIpAddr(request));

        //调用service保存SysLog实体类到数据库
        houseService.addLog(sysLog);
        return object;
    }

}
